package jk.fox.spring.processor;

import jk.fox.spring.bootstrap.SpringRpcContext;
import jk.fox.annotaion.RpcReference;
import org.springframework.beans.factory.annotation.InjectionMetadata;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.core.annotation.AnnotationAttributes;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * Rpc-服务消费者处理器
 * @author cuichao
 * @Description: RpcReferenceBeanPostProcessor
 * @Date: create in 2020/5/25 23:42
 */
public class RpcReferenceBeanPostProcessor extends AbstractAnnotationBeanPostProcessor {

    private final String referenceKeySuffix = "_Reference";

    private final ConcurrentMap<String, Object> referenceBeanCache = new ConcurrentHashMap<>(128);

    public RpcReferenceBeanPostProcessor() {
        super(RpcReference.class);
    }

    @Override
    protected Object doGetInjectedBean(AnnotationAttributes attributes, Object bean, String beanName, Class<?> injectedType, InjectionMetadata.InjectedElement injectedElement) {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        SpringRpcContext context = beanFactory.getBean(SpringRpcContext.class);
        //由于同源载入消费代理对象不纳入Spring-ioc中 只返回引用
        Object reference= context.registryReference(injectedType.getName(), injectedType, attributes);
        return  reference;
    }

    @Override
    protected String buildInjectedObjectCacheKey(AnnotationAttributes attributes, Object bean, String beanName, Class<?> injectedType, InjectionMetadata.InjectedElement injectedElement) {
        String name = injectedType.getName();
        /*String id = attributes.getString("id");
        if(!StringUtils.isEmpty(id)){
            name = id;
        }*/
        return name+referenceKeySuffix;
    }

    @Override
    public void destroy() throws Exception {
        super.destroy();
        referenceBeanCache.clear();
    }
}
